// 全局变量
let scene, camera, renderer, controls;
let pointCloudMesh = null;
let fovOriginalPointCloudMesh = null;
let coloredPointCloudMesh = null;
let uploadedFiles = {
    pointcloud: null,
    image: null,
    calib: null
};
let processedData = {
    originalPoints: null,
    fovOriginalPoints: null,
    coloredPoints: null,
    colors: null
};

// 3D导航相关变量
let defaultCameraPosition = { x: 0, y: 0, z: 50 };
let defaultCameraTarget = { x: 0, y: 0, z: 0 };
let currentViewMode = 'free';
let keyPressed = {};

// 初始化应用
document.addEventListener('DOMContentLoaded', function() {
    initializeApp();
    setupEventListeners();
    initThreeJS();
    setupIntensityToggle();
});

// 初始化应用
async function initializeApp() {
    console.log('点云图像融合可视化系统初始化...');
    updateFileStatus();
    hideLoadingOverlay();
    
    // 重置点云数量显示
    document.getElementById('original-points-count').textContent = '-';
    document.getElementById('colored-points-count').textContent = '-';
    document.getElementById('projection-rate').textContent = '-';

    // 检查后端API连接状态
    await initializeBackendConnection();
}

// 设置事件监听器
function setupEventListeners() {
    // 文件上传事件
    setupFileUpload('pointcloud-upload', 'pointcloud-area', 'pointcloud-status', 'pointcloud');
    setupFileUpload('image-upload', 'image-area', 'image-status', 'image');
    setupFileUpload('calib-upload', 'calib-area', 'calib-status', 'calib');
    
    // 处理按钮 - 添加错误检查
    const processBtn = document.getElementById('process-btn');
    if (processBtn) {
        processBtn.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            console.log('融合按钮被点击');
            processFiles();
        });
        console.log('✅ 融合按钮事件监听器已绑定');
    } else {
        console.error('❌ 找不到融合按钮元素 (process-btn)');
    }

    // 导出按钮
    const exportBtn = document.getElementById('export-btn');
    if (exportBtn) {
        exportBtn.addEventListener('click', exportColoredPointCloud);
        console.log('✅ 导出按钮事件监听器已绑定');
    } else {
        console.error('❌ 找不到导出按钮元素 (export-btn)');
    }
    
    // 视图控制按钮 - 支持上方和下方的按钮
    document.querySelectorAll('.view-btn, .view-btn-bottom').forEach(btn => {
        btn.addEventListener('click', function() {
            switchView(this.dataset.view);
            updateActiveButton(this);
        });
    });
    
    // 渲染设置滑块
    const pointSizeInput = document.getElementById('point-size');
    if (pointSizeInput) {
        pointSizeInput.addEventListener('input', function() {
            const pointSizeValue = document.getElementById('point-size-value');
            if (pointSizeValue) {
                pointSizeValue.textContent = this.value;
            }
            updatePointSize(parseFloat(this.value));
        });
    }
    
    // 模态对话框
    document.getElementById('modal-close').addEventListener('click', hideModal);
    document.getElementById('modal-ok').addEventListener('click', hideModal);

    // 键盘控制
    setupKeyboardControls();
}

// 设置强度开关的交互
function setupIntensityToggle() {
    const intensityCheckbox = document.getElementById('include-intensity');
    const intensityStatus = document.getElementById('intensity-status');
    
    if (!intensityCheckbox || !intensityStatus) {
        return;
    }
    
    function updateIntensityStatus() {
        if (intensityCheckbox.checked) {
            intensityStatus.textContent = '✓ 包含强度：7维数据 (x, y, z, r, g, b, intensity)';
            intensityStatus.className = 'toggle-status';
            intensityStatus.style.background = '#e8f5e8';
            intensityStatus.style.color = '#27ae60';
        } else {
            intensityStatus.textContent = '✗ 不包含强度：6维数据 (x, y, z, r, g, b)';
            intensityStatus.className = 'toggle-status inactive';
            intensityStatus.style.background = '#f1f3f4';
            intensityStatus.style.color = '#6c757d';
        }
    }
    
    // 初始化显示状态
    updateIntensityStatus();
    
    // 监听开关变化
    intensityCheckbox.addEventListener('change', updateIntensityStatus);
}

// 设置文件上传
function setupFileUpload(inputId, areaId, statusId, fileType) {
    const input = document.getElementById(inputId);
    const area = document.getElementById(areaId);
    const status = document.getElementById(statusId);
    
    // 点击上传
    input.addEventListener('change', function(e) {
        handleFileSelect(e.target.files[0], fileType, area, status);
    });
    
    // 拖拽上传
    area.addEventListener('dragover', function(e) {
        e.preventDefault();
        area.classList.add('dragover');
    });
    
    area.addEventListener('dragleave', function(e) {
        e.preventDefault();
        area.classList.remove('dragover');
    });
    
    area.addEventListener('drop', function(e) {
        e.preventDefault();
        area.classList.remove('dragover');
        const file = e.dataTransfer.files[0];
        handleFileSelect(file, fileType, area, status);
    });
}

// 处理文件选择
function handleFileSelect(file, fileType, area, status) {
    if (!file) return;
    
    // 验证文件类型
    const validExtensions = {
        pointcloud: ['.bin'],
        image: ['.png', '.jpg', '.jpeg'],
        calib: ['.txt']
    };
    
    const fileName = file.name.toLowerCase();
    const isValid = validExtensions[fileType].some(ext => fileName.endsWith(ext));
    
    if (!isValid) {
        showError(`请选择正确的${fileType}文件格式`);
        return;
    }
    
    // 保存文件
    uploadedFiles[fileType] = file;
    
    // 更新UI
    area.classList.add('uploaded');
    status.textContent = `已选择: ${file.name}`;
    status.classList.add('uploaded');
    
    // 如果是图像文件，显示预览
    if (fileType === 'image') {
        previewImage(file);
    }
    
    updateFileStatus();
    console.log(`${fileType}文件已上传:`, file.name);
}

// 预览图像
function previewImage(file) {
    const reader = new FileReader();
    reader.onload = function(e) {
        const img = document.getElementById('display-image');
        img.src = e.target.result;
        
        // 更新图像信息
        const info = document.getElementById('image-info-text');
        info.textContent = `${file.name} (${(file.size / 1024 / 1024).toFixed(2)} MB)`;
    };
    reader.readAsDataURL(file);
}

// 更新文件状态
function updateFileStatus() {
    const allUploaded = uploadedFiles.pointcloud && uploadedFiles.image && uploadedFiles.calib;
    const processBtn = document.getElementById('process-btn');
    const filesStatus = document.getElementById('files-status');
    
    if (processBtn) {
        processBtn.disabled = !allUploaded;
    }
    
    if (filesStatus) {
        if (allUploaded) {
            filesStatus.textContent = '文件就绪';
            filesStatus.style.color = '#27ae60';
        } else {
            const uploaded = Object.values(uploadedFiles).filter(f => f !== null).length;
            filesStatus.textContent = `已上传 ${uploaded}/3 个文件`;
            filesStatus.style.color = '#f39c12';
        }
    }
}

// 处理文件
async function processFiles() {
    console.log('processFiles 函数被调用');
    console.log('uploadedFiles 状态:', {
        pointcloud: !!uploadedFiles.pointcloud,
        image: !!uploadedFiles.image,
        calib: !!uploadedFiles.calib
    });
    
    if (!uploadedFiles.pointcloud || !uploadedFiles.image || !uploadedFiles.calib) {
        console.error('❌ 文件未全部上传');
        showError('请先上传所有必需的文件');
        return;
    }

    console.log('✅ 所有文件已上传，开始处理');
    showLoadingOverlay();
    updateProcessStatus('正在处理文件...', 10);

    try {
        // 首先尝试使用后端API
        let result;
        try {
            result = await performFusionWithAPI();
            updateProcessStatus('正在生成可视化...', 80);
        } catch (apiError) {
            console.warn('后端API不可用，使用本地处理:', apiError.message);

            // 如果API不可用，回退到本地处理
            updateProcessStatus('正在读取文件...', 20);
            const pointcloudData = await readBinaryFile(uploadedFiles.pointcloud);
            const imageData = await readImageFile(uploadedFiles.image);
            const calibData = await readTextFile(uploadedFiles.calib);

            updateProcessStatus('正在解析数据...', 40);
            const points = parsePointCloudData(pointcloudData);
            processedData.originalPoints = points;

            updateProcessStatus('正在进行融合处理...', 60);
            await simulateFusionProcess(points, imageData, calibData);

            updateProcessStatus('正在生成可视化...', 80);
        }

        // 创建3D可视化
        createPointCloudVisualization();

        updateProcessStatus('处理完成', 100);

        // 更新点云数量显示 - 融合前后
        let originalPointCount = 0;
        let coloredPointCount = 0;
        let projectionRate = 0;
        
        if (processedData.projectionInfo) {
            originalPointCount = processedData.projectionInfo.total_points;
            coloredPointCount = processedData.projectionInfo.valid_points;
            projectionRate = processedData.projectionInfo.projection_rate;
            
            // 更新UI显示
            const originalCountEl = document.getElementById('original-points-count');
            const coloredCountEl = document.getElementById('colored-points-count');
            const rateEl = document.getElementById('projection-rate');
            
            if (originalCountEl) {
                originalCountEl.textContent = originalPointCount.toLocaleString() + ' 个点';
            }
            if (coloredCountEl) {
                coloredCountEl.textContent = coloredPointCount.toLocaleString() + ' 个点';
            }
            if (rateEl) {
                rateEl.textContent = projectionRate.toFixed(2) + '%';
            }
            
            console.log('✅ 融合统计信息:', {
                融合前点云: originalPointCount.toLocaleString(),
                融合后点云: coloredPointCount.toLocaleString(),
                投影成功率: projectionRate.toFixed(2) + '%'
            });
        } else {
            // 备用方案：从其他数据源获取
            if (processedData.originalPointsThreeJS) {
                originalPointCount = processedData.originalPointsThreeJS.count;
            } else if (processedData.originalPoints) {
                originalPointCount = processedData.originalPoints.length;
            }
            
            if (processedData.coloredPointsThreeJS) {
                coloredPointCount = processedData.coloredPointsThreeJS.count;
            } else if (processedData.coloredPoints) {
                coloredPointCount = processedData.coloredPoints.length;
            }
            
            const originalCountEl = document.getElementById('original-points-count');
            const coloredCountEl = document.getElementById('colored-points-count');
            const rateEl = document.getElementById('projection-rate');
            
            if (originalCountEl) {
                originalCountEl.textContent = originalPointCount.toLocaleString() + ' 个点';
            }
            if (coloredCountEl) {
                coloredCountEl.textContent = coloredPointCount.toLocaleString() + ' 个点';
            }
            
            if (originalPointCount > 0) {
                projectionRate = (coloredPointCount / originalPointCount) * 100;
                if (rateEl) {
                    rateEl.textContent = projectionRate.toFixed(2) + '%';
                }
            }
        }

        // 启用导出按钮
        const exportBtn = document.getElementById('export-btn');
        if (exportBtn) {
            // 检查是否有可导出的数据（Three.js格式或传统格式）
            const hasColoredData = (processedData.coloredPointsThreeJS && processedData.coloredPointsThreeJS.positions && processedData.coloredPointsThreeJS.positions.length > 0) ||
                                   (processedData.coloredPoints && processedData.coloredPoints.length > 0);
            
            if (hasColoredData) {
                exportBtn.disabled = false;
                console.log('导出按钮已启用 - 检测到彩色点云数据');
            } else {
                console.log('导出按钮保持禁用 - 未检测到彩色点云数据');
            }
        }

        hideLoadingOverlay();
        console.log('文件处理完成');

    } catch (error) {
        console.error('处理文件时出错:', error);
        showError('处理文件时出错: ' + error.message);
        hideLoadingOverlay();
    }
}

// 读取二进制文件
function readBinaryFile(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = function(e) {
            resolve(new Float32Array(e.target.result));
        };
        reader.onerror = reject;
        reader.readAsArrayBuffer(file);
    });
}

// 读取图像文件
function readImageFile(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = function(e) {
            const img = new Image();
            img.onload = function() {
                const canvas = document.createElement('canvas');
                const ctx = canvas.getContext('2d');
                canvas.width = img.width;
                canvas.height = img.height;
                ctx.drawImage(img, 0, 0);
                const imageData = ctx.getImageData(0, 0, img.width, img.height);
                resolve({
                    data: imageData,
                    width: img.width,
                    height: img.height
                });
            };
            img.onerror = reject;
            img.src = e.target.result;
        };
        reader.onerror = reject;
        reader.readAsDataURL(file);
    });
}

// 读取文本文件
function readTextFile(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = function(e) {
            resolve(e.target.result);
        };
        reader.onerror = reject;
        reader.readAsText(file);
    });
}

// 解析点云数据
function parsePointCloudData(data) {
    const points = [];
    // KITTI格式：每个点包含x,y,z,intensity四个float32值
    for (let i = 0; i < data.length; i += 4) {
        points.push({
            x: data[i],
            y: data[i + 1],
            z: data[i + 2],
            intensity: data[i + 3]
        });
    }
    return points;
}

// 调用后端API进行融合处理
async function performFusionWithAPI() {
    try {
        // 1. 上传文件到后端
        updateProcessStatus('正在上传文件...', 20);
        console.log('开始上传文件到后端...');
        const formData = new FormData();
        formData.append('pointcloud', uploadedFiles.pointcloud);
        formData.append('image', uploadedFiles.image);
        formData.append('calib', uploadedFiles.calib);

        console.log('上传的文件:', {
            pointcloud: uploadedFiles.pointcloud?.name,
            image: uploadedFiles.image?.name,
            calib: uploadedFiles.calib?.name
        });

        const uploadResponse = await fetch('http://localhost:5000/api/upload', {
            method: 'POST',
            body: formData
        });

        console.log('上传响应状态:', uploadResponse.status);
        
        if (!uploadResponse.ok) {
            const errorText = await uploadResponse.text();
            console.error('上传失败响应:', errorText);
            throw new Error(`文件上传失败: ${uploadResponse.status}`);
        }

        const uploadResult = await uploadResponse.json();
        console.log('上传结果:', uploadResult);
        
        if (!uploadResult.success) {
            throw new Error(`上传失败: ${uploadResult.error}`);
        }
        
        console.log('✅ 文件上传成功');

        // 2. 调用融合处理API
        updateProcessStatus('正在进行融合处理...', 60);
        console.log('开始融合处理...');
        console.log('文件路径:', uploadResult.file_paths);
        
        const processResponse = await fetch('http://localhost:5000/api/process', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                file_paths: uploadResult.file_paths
            })
        });

        console.log('融合响应状态:', processResponse.status);
        
        if (!processResponse.ok) {
            const errorText = await processResponse.text();
            console.error('融合失败响应:', errorText);
            throw new Error(`融合处理失败: ${processResponse.status}`);
        }

        const processResult = await processResponse.json();
        console.log('融合结果:', processResult);
        
        if (!processResult.success) {
            throw new Error(`融合失败: ${processResult.error}`);
        }
        
        console.log('✅ 融合处理成功');

        // 3. 处理返回的数据
        const result = processResult.result;

        // 使用新的Three.js格式数据（更高效）
        if (result.threejs_data) {
            // 直接使用Three.js格式的数据
            processedData.originalPointsThreeJS = {
                positions: result.threejs_data.original_positions,
                colors: result.threejs_data.original_colors,
                count: result.threejs_data.point_count.original
            };

            // 图像范围内的原始点云数据
            processedData.fovOriginalPointsThreeJS = {
                positions: result.threejs_data.fov_original_positions,
                colors: result.threejs_data.fov_original_colors,
                count: result.threejs_data.point_count.colored
            };

            // 调试信息
            console.log('Three.js数据调试:', {
                hasFovOriginalPositions: !!result.threejs_data.fov_original_positions,
                fovOriginalPositionsLength: result.threejs_data.fov_original_positions ? result.threejs_data.fov_original_positions.length : 0,
                hasFovOriginalColors: !!result.threejs_data.fov_original_colors,
                fovOriginalColorsLength: result.threejs_data.fov_original_colors ? result.threejs_data.fov_original_colors.length : 0
            });

            processedData.coloredPointsThreeJS = {
                positions: result.threejs_data.colored_positions,
                colors: result.threejs_data.colored_colors,
                count: result.threejs_data.point_count.colored
            };

            // 设置推荐的渲染参数
            if (result.threejs_data.recommended_point_size) {
                const pointSizeInput = document.getElementById('point-size');
                const pointSizeValue = document.getElementById('point-size-value');
                if (pointSizeInput) {
                    pointSizeInput.value = result.threejs_data.recommended_point_size;
                }
                if (pointSizeValue) {
                    pointSizeValue.textContent = result.threejs_data.recommended_point_size;
                }
            }

            // 设置推荐的相机位置
            if (result.threejs_data.camera_suggestion) {
                const suggestion = result.threejs_data.camera_suggestion;
                defaultCameraPosition = {
                    x: suggestion.position[0],
                    y: suggestion.position[1],
                    z: suggestion.position[2]
                };
                defaultCameraTarget = {
                    x: suggestion.target[0],
                    y: suggestion.target[1],
                    z: suggestion.target[2]
                };
            }
        }

        // 始终设置传统格式数据（用于导出时获取intensity信息）
        if (result.original_points) {
            processedData.originalPoints = result.original_points.data.map(point => ({
                x: point[0],
                y: point[1],
                z: point[2],
                intensity: point[3] || 0
            }));

            // 图像范围内的原始点云数据（包含intensity，用于导出）
            processedData.fovOriginalPoints = result.valid_points.data_with_intensity || result.valid_points.data;
            
            // 调试信息
            console.log('fovOriginalPoints设置调试:', {
                hasDataWithIntensity: !!result.valid_points.data_with_intensity,
                dataWithIntensitySample: result.valid_points.data_with_intensity ? result.valid_points.data_with_intensity.slice(0, 2) : 'undefined',
                fallbackDataSample: result.valid_points.data ? result.valid_points.data.slice(0, 2) : 'undefined',
                finalFovOriginalPoints: processedData.fovOriginalPoints ? processedData.fovOriginalPoints.slice(0, 2) : 'undefined'
            });

            // 只有在没有Three.js格式数据时才创建传统格式的coloredPoints
            if (!processedData.coloredPointsThreeJS) {
                processedData.coloredPoints = result.valid_points.data.map((point, index) => ({
                    x: point[0],
                    y: point[1],
                    z: point[2],
                    intensity: result.valid_points.data_with_intensity && result.valid_points.data_with_intensity[index] ? 
                              result.valid_points.data_with_intensity[index][3] : 0,
                    r: result.colors[index][0],
                    g: result.colors[index][1],
                    b: result.colors[index][2]
                }));
            }
        }

        // 保存颜色数据和统计信息
        processedData.colors = result.colors;
        processedData.projectionInfo = result.projection_info;

        console.log('融合处理完成:', {
            原始点云数量: result.original_points.count,
            有效点云数量: result.valid_points.count,
            投影成功率: result.projection_info.projection_rate.toFixed(2) + '%'
        });

        // 调试：检查intensity数据分布
        if (processedData.fovOriginalPoints && processedData.fovOriginalPoints.length > 0) {
            const intensityValues = processedData.fovOriginalPoints.map(point => point[3]);
            const nonZeroCount = intensityValues.filter(val => val > 0).length;
            const maxIntensity = Math.max(...intensityValues);
            const avgIntensity = intensityValues.reduce((sum, val) => sum + val, 0) / intensityValues.length;
            
            console.log('图像范围内intensity统计:', {
                总点数: intensityValues.length,
                非零intensity数量: nonZeroCount,
                非零比例: `${(nonZeroCount / intensityValues.length * 100).toFixed(2)}%`,
                最大intensity: maxIntensity,
                平均intensity: avgIntensity.toFixed(4),
                前10个intensity值: intensityValues.slice(0, 10)
            });
        }

        // 调试：检查关键数据
        console.log('processedData调试信息:', {
            fovOriginalPoints: processedData.fovOriginalPoints ? processedData.fovOriginalPoints.slice(0, 2) : 'undefined',
            fovOriginalPointsLength: processedData.fovOriginalPoints ? processedData.fovOriginalPoints.length : 0,
            coloredPoints: processedData.coloredPoints ? processedData.coloredPoints.slice(0, 2) : 'undefined',
            coloredPointsLength: processedData.coloredPoints ? processedData.coloredPoints.length : 0,
            fovOriginalPointsThreeJS: processedData.fovOriginalPointsThreeJS ? 'exists' : 'undefined'
        });

        return result;

    } catch (error) {
        console.error('API调用失败:', error);
        throw error;
    }
}

// 模拟融合处理（备用方案）
async function simulateFusionProcess(points, imageData, calibData) {
    // 如果后端API不可用，使用模拟数据
    console.log('使用模拟融合处理...');

    return new Promise(resolve => {
        setTimeout(() => {
            const coloredPoints = points.map(point => ({
                ...point,
                r: Math.random() * 255,
                g: Math.random() * 255,
                b: Math.random() * 255
            }));

            processedData.coloredPoints = coloredPoints;
            resolve();
        }, 1000);
    });
}

// 初始化Three.js
function initThreeJS() {
    const container = document.getElementById('three-container');
    
    // 创建场景
    scene = new THREE.Scene();
    scene.background = new THREE.Color(0x1a1a1a);
    
    // 创建相机
    camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);
    camera.position.set(0, 0, 50);
    
    // 创建渲染器
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(container.clientWidth, container.clientHeight);
    renderer.setPixelRatio(window.devicePixelRatio);
    container.appendChild(renderer.domElement);
    
    // 创建控制器
    controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.dampingFactor = 0.05;
    
    // 添加光源
    const ambientLight = new THREE.AmbientLight(0x404040, 0.6);
    scene.add(ambientLight);
    
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
    directionalLight.position.set(1, 1, 1);
    scene.add(directionalLight);
    
    // 添加坐标轴
    const axesHelper = new THREE.AxesHelper(10);
    scene.add(axesHelper);
    
    // 开始渲染循环
    animate();
    
    // 处理窗口大小变化
    window.addEventListener('resize', onWindowResize);
}

// 创建点云可视化
function createPointCloudVisualization() {
    // 清除现有的点云
    if (pointCloudMesh) {
        scene.remove(pointCloudMesh);
    }
    if (fovOriginalPointCloudMesh) {
        scene.remove(fovOriginalPointCloudMesh);
    }
    if (coloredPointCloudMesh) {
        scene.remove(coloredPointCloudMesh);
    }

    // 优先使用Three.js格式数据（更高效）
    if (processedData.originalPointsThreeJS) {
        // 创建原始点云
        pointCloudMesh = createPointCloudFromThreeJSData(
            processedData.originalPointsThreeJS.positions,
            processedData.originalPointsThreeJS.colors,
            false
        );
        scene.add(pointCloudMesh);

        // 创建图像范围内的原始点云
        if (processedData.fovOriginalPointsThreeJS) {
            fovOriginalPointCloudMesh = createPointCloudFromThreeJSData(
                processedData.fovOriginalPointsThreeJS.positions,
                processedData.fovOriginalPointsThreeJS.colors,
                false
            );
            fovOriginalPointCloudMesh.visible = false;
            scene.add(fovOriginalPointCloudMesh);
        }

        // 创建彩色点云
        if (processedData.coloredPointsThreeJS) {
            coloredPointCloudMesh = createPointCloudFromThreeJSData(
                processedData.coloredPointsThreeJS.positions,
                processedData.coloredPointsThreeJS.colors,
                true
            );
            coloredPointCloudMesh.visible = false;
            scene.add(coloredPointCloudMesh);
        }
    }
    // 备用：使用旧格式数据
    else if (processedData.originalPoints) {
        pointCloudMesh = createPointCloud(processedData.originalPoints, false);
        scene.add(pointCloudMesh);

        if (processedData.coloredPoints) {
            coloredPointCloudMesh = createPointCloud(processedData.coloredPoints, true);
            coloredPointCloudMesh.visible = false;
            scene.add(coloredPointCloudMesh);
        }
    }

    // 自动适应相机位置
    fitCameraToPointCloud();
}

// 创建点云对象（旧格式兼容）
function createPointCloud(points, colored = false) {
    const geometry = new THREE.BufferGeometry();
    const positions = [];
    const colors = [];

    points.forEach(point => {
        positions.push(point.x, point.y, point.z);

        if (colored && point.r !== undefined) {
            colors.push(point.r / 255, point.g / 255, point.b / 255);
        } else {
            // 基于强度或高度着色
            const intensity = point.intensity || point.z;
            const normalizedIntensity = Math.max(0, Math.min(1, (intensity + 10) / 20));
            colors.push(normalizedIntensity, normalizedIntensity, normalizedIntensity);
        }
    });

    geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
    geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

    const pointSizeEl = document.getElementById('point-size');
    const pointSize = pointSizeEl ? parseFloat(pointSizeEl.value) : 0.5;
    
    const material = new THREE.PointsMaterial({
        size: pointSize || 0.5,
        vertexColors: true,
        sizeAttenuation: true
    });

    return new THREE.Points(geometry, material);
}

// 创建点云对象（Three.js格式，高效版本）
function createPointCloudFromThreeJSData(positions, colors, colored = false) {
    const geometry = new THREE.BufferGeometry();

    // 直接使用预处理的数据，无需转换
    geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
    geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

    // 计算边界框以优化渲染
    geometry.computeBoundingBox();
    geometry.computeBoundingSphere();

    const pointSizeEl = document.getElementById('point-size');
    const pointSize = pointSizeEl ? parseFloat(pointSizeEl.value) : 0.5;

    const material = new THREE.PointsMaterial({
        size: pointSize || 0.5,
        vertexColors: true,
        sizeAttenuation: true,
        // 添加性能优化选项
        alphaTest: 0.1,
        transparent: false
    });

    const pointCloud = new THREE.Points(geometry, material);

    // 添加标识以便后续识别
    pointCloud.userData.isColored = colored;
    pointCloud.userData.pointCount = positions.length / 3;

    return pointCloud;
}

// 渲染循环
function animate() {
    requestAnimationFrame(animate);

    // 处理键盘移动控制
    handleKeyboardMovement();

    if (controls) {
        controls.update();
    }

    if (renderer && scene && camera) {
        renderer.render(scene, camera);
    }

    // 更新FPS显示
    updateFPS();

    // 定期更新相机信息（每30帧更新一次以避免过于频繁）
    if (frameCount % 30 === 0) {
        updateCameraInfo();
    }
}

// 更新FPS显示
let lastTime = performance.now();
let frameCount = 0;
function updateFPS() {
    frameCount++;
    const currentTime = performance.now();
    if (currentTime - lastTime >= 1000) {
        const fps = Math.round((frameCount * 1000) / (currentTime - lastTime));
        const fpsEl = document.getElementById('fps-counter');
        if (fpsEl) {
            fpsEl.textContent = fps;
        }
        frameCount = 0;
        lastTime = currentTime;
    }
}

// 窗口大小变化处理
function onWindowResize() {
    const container = document.getElementById('three-container');
    camera.aspect = container.clientWidth / container.clientHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(container.clientWidth, container.clientHeight);
}

// 切换视图
function switchView(viewType) {
    const threeContainer = document.getElementById('three-container');
    const imageContainer = document.getElementById('image-container');
    const renderMode = document.getElementById('render-mode');
    
    if (!threeContainer || !imageContainer) return;
    
    // 隐藏所有容器
    threeContainer.style.display = 'none';
    imageContainer.style.display = 'none';
    
    // 隐藏所有点云
    if (pointCloudMesh) pointCloudMesh.visible = false;
    if (fovOriginalPointCloudMesh) fovOriginalPointCloudMesh.visible = false;
    if (coloredPointCloudMesh) coloredPointCloudMesh.visible = false;
    
    switch (viewType) {
        case 'original-pointcloud':
            threeContainer.style.display = 'block';
            if (pointCloudMesh) pointCloudMesh.visible = true;
            if (renderMode) renderMode.textContent = '原始点云';
            break;
        case 'fov-original-pointcloud':
            threeContainer.style.display = 'block';
            if (fovOriginalPointCloudMesh) fovOriginalPointCloudMesh.visible = true;
            if (renderMode) renderMode.textContent = '图像范围内原始点云';
            break;
        case 'colored-pointcloud':
            threeContainer.style.display = 'block';
            if (coloredPointCloudMesh) coloredPointCloudMesh.visible = true;
            if (renderMode) renderMode.textContent = '彩色点云';
            break;
        case 'image':
            imageContainer.style.display = 'flex';
            if (renderMode) renderMode.textContent = '图像模式';
            break;
    }
}

// 更新活动按钮 - 同时更新上方和下方的按钮
function updateActiveButton(activeBtn) {
    document.querySelectorAll('.view-btn, .view-btn-bottom').forEach(btn => {
        btn.classList.remove('active');
    });
    activeBtn.classList.add('active');
}

// 更新点大小
function updatePointSize(size) {
    if (pointCloudMesh && pointCloudMesh.material) {
        pointCloudMesh.material.size = size;
    }
    if (fovOriginalPointCloudMesh && fovOriginalPointCloudMesh.material) {
        fovOriginalPointCloudMesh.material.size = size;
    }
    if (coloredPointCloudMesh && coloredPointCloudMesh.material) {
        coloredPointCloudMesh.material.size = size;
    }
}

// 更新点密度
function updatePointDensity(density) {
    // 这里可以实现点云密度控制逻辑
    console.log('更新点密度:', density + '%');
}

// 更新处理状态
function updateProcessStatus(status, progress) {
    const statusElement = document.getElementById('process-status');
    const progressElement = document.getElementById('progress-fill');
    
    if (statusElement) {
        statusElement.textContent = status;
    } else {
        console.warn('⚠️ 找不到 process-status 元素');
    }
    
    if (progressElement) {
        progressElement.style.width = progress + '%';
    } else {
        console.warn('⚠️ 找不到 progress-fill 元素');
    }
}

// 显示加载覆盖层
function showLoadingOverlay() {
    const overlay = document.getElementById('loading-overlay');
    if (overlay) {
        overlay.style.display = 'flex';
    } else {
        console.warn('⚠️ 找不到 loading-overlay 元素');
    }
}

// 隐藏加载覆盖层
function hideLoadingOverlay() {
    const overlay = document.getElementById('loading-overlay');
    if (overlay) {
        overlay.style.display = 'none';
    } else {
        console.warn('⚠️ 找不到 loading-overlay 元素');
    }
}

// 显示错误模态框
function showError(message) {
    const errorMsg = document.getElementById('error-message');
    const errorModal = document.getElementById('error-modal');
    
    if (errorMsg) {
        errorMsg.textContent = message;
    } else {
        console.warn('⚠️ 找不到 error-message 元素');
    }
    
    if (errorModal) {
        errorModal.style.display = 'block';
    } else {
        console.warn('⚠️ 找不到 error-modal 元素');
    }
}

// 隐藏模态框
function hideModal() {
    const errorModal = document.getElementById('error-modal');
    if (errorModal) {
        errorModal.style.display = 'none';
    } else {
        console.warn('⚠️ 找不到 error-modal 元素');
    }
}

// 显示导出成功提示
function showExportSuccess(filename, format, pointCount, includeIntensity) {
    const dimensions = includeIntensity ? '7维 (x,y,z,intensity,r,g,b)' : '6维 (x,y,z,r,g,b)';
    const message = `导出成功！\n\n文件名: ${filename}.${format}\n点云数量: ${pointCount.toLocaleString()}\n数据格式: ${dimensions}`;

    // 创建成功提示模态框
    const modal = document.createElement('div');
    modal.className = 'modal success-modal';
    modal.innerHTML = `
        <div class="modal-content">
            <div class="modal-header success-header">
                <h3>✅ 导出成功</h3>
                <button class="modal-close">&times;</button>
            </div>
            <div class="modal-body">
                <p style="white-space: pre-line;">${message}</p>
            </div>
            <div class="modal-footer">
                <button class="btn btn-success">确定</button>
            </div>
        </div>
    `;

    document.body.appendChild(modal);
    modal.style.display = 'block';

    // 添加关闭事件
    const closeBtn = modal.querySelector('.modal-close');
    const okBtn = modal.querySelector('.btn-success');

    const closeModal = () => {
        document.body.removeChild(modal);
    };

    closeBtn.addEventListener('click', closeModal);
    okBtn.addEventListener('click', closeModal);

    // 3秒后自动关闭
    setTimeout(closeModal, 3000);
}

// 设置3D导航控制
function setupNavigationControls() {
    // 预设视角按钮
    document.querySelectorAll('.nav-btn[data-view]').forEach(btn => {
        btn.addEventListener('click', function() {
            const viewType = this.dataset.view;
            setPresetView(viewType);
            updateActiveViewButton(this);
        });
    });

    // 重置视角按钮
    document.getElementById('reset-view').addEventListener('click', resetCameraView);
}

// 设置键盘控制
function setupKeyboardControls() {
    document.addEventListener('keydown', function(e) {
        keyPressed[e.key.toLowerCase()] = true;

        // 处理单次按键事件
        switch(e.key.toLowerCase()) {
            case 'r':
                resetCameraView();
                break;
            case '1':
                setPresetView('front');
                break;
            case '2':
                setPresetView('back');
                break;
            case '3':
                setPresetView('right');
                break;
            case '4':
                setPresetView('left');
                break;
            case '5':
                setPresetView('top');
                break;
            case '6':
                setPresetView('bottom');
                break;
            case '7':
                setPresetView('iso');
                break;
        }
    });

    document.addEventListener('keyup', function(e) {
        keyPressed[e.key.toLowerCase()] = false;
    });
}

// 设置预设视角
function setPresetView(viewType) {
    if (!camera || !controls) return;

    const distance = 50; // 相机距离
    let position, target;

    switch(viewType) {
        case 'front':
            position = { x: 0, y: 0, z: distance };
            target = { x: 0, y: 0, z: 0 };
            currentViewMode = '正视图';
            break;
        case 'back':
            position = { x: 0, y: 0, z: -distance };
            target = { x: 0, y: 0, z: 0 };
            currentViewMode = '后视图';
            break;
        case 'left':
            position = { x: -distance, y: 0, z: 0 };
            target = { x: 0, y: 0, z: 0 };
            currentViewMode = '左视图';
            break;
        case 'right':
            position = { x: distance, y: 0, z: 0 };
            target = { x: 0, y: 0, z: 0 };
            currentViewMode = '右视图';
            break;
        case 'top':
            position = { x: 0, y: distance, z: 0 };
            target = { x: 0, y: 0, z: 0 };
            currentViewMode = '俯视图';
            break;
        case 'bottom':
            position = { x: 0, y: -distance, z: 0 };
            target = { x: 0, y: 0, z: 0 };
            currentViewMode = '仰视图';
            break;
        case 'iso':
            position = { x: distance * 0.7, y: distance * 0.7, z: distance * 0.7 };
            target = { x: 0, y: 0, z: 0 };
            currentViewMode = '等轴视图';
            break;
        default:
            return;
    }

    // 平滑过渡到新视角
    animateCameraToPosition(position, target);
}

// 相机位置动画
function animateCameraToPosition(targetPosition, targetLookAt, duration = 1000) {
    if (!camera || !controls) return;

    const startPosition = camera.position.clone();
    const startTarget = controls.target.clone();
    const startTime = performance.now();

    function animate() {
        const elapsed = performance.now() - startTime;
        const progress = Math.min(elapsed / duration, 1);

        // 使用缓动函数
        const easeProgress = 1 - Math.pow(1 - progress, 3);

        // 插值位置
        camera.position.lerpVectors(startPosition, new THREE.Vector3(targetPosition.x, targetPosition.y, targetPosition.z), easeProgress);
        controls.target.lerpVectors(startTarget, new THREE.Vector3(targetLookAt.x, targetLookAt.y, targetLookAt.z), easeProgress);

        controls.update();

        if (progress < 1) {
            requestAnimationFrame(animate);
        }
    }

    animate();
}

// 重置相机视角
function resetCameraView() {
    if (!camera || !controls) return;

    currentViewMode = '自由视角';
    animateCameraToPosition(defaultCameraPosition, defaultCameraTarget);

    // 重置所有视角按钮状态
    document.querySelectorAll('.nav-btn[data-view]').forEach(btn => {
        btn.classList.remove('active');
    });

    updateCameraInfo();
}

// 更新活动视角按钮
function updateActiveViewButton(activeBtn) {
    document.querySelectorAll('.nav-btn[data-view]').forEach(btn => {
        btn.classList.remove('active');
    });
    activeBtn.classList.add('active');
    updateCameraInfo();
}

// 更新相机信息显示
function updateCameraInfo() {
    if (!camera) return;

    const cameraInfoEl = document.getElementById('camera-info');
    const cameraPositionEl = document.getElementById('camera-position');
    
    if (!cameraInfoEl || !cameraPositionEl) return;

    const pos = camera.position;
    cameraInfoEl.textContent = currentViewMode;
    cameraPositionEl.textContent =
        `X:${pos.x.toFixed(1)} Y:${pos.y.toFixed(1)} Z:${pos.z.toFixed(1)}`;
}

// 处理键盘移动控制
function handleKeyboardMovement() {
    if (!camera || !controls) return;

    const moveSpeed = 2;
    const moveVector = new THREE.Vector3();

    if (keyPressed['w']) moveVector.z -= moveSpeed;
    if (keyPressed['s']) moveVector.z += moveSpeed;
    if (keyPressed['a']) moveVector.x -= moveSpeed;
    if (keyPressed['d']) moveVector.x += moveSpeed;
    if (keyPressed['q']) moveVector.y += moveSpeed;
    if (keyPressed['e']) moveVector.y -= moveSpeed;

    if (moveVector.length() > 0) {
        // 将移动向量转换到相机坐标系
        moveVector.applyQuaternion(camera.quaternion);
        camera.position.add(moveVector);
        controls.target.add(moveVector);
        controls.update();
        updateCameraInfo();
    }
}

// 自动适应点云大小
function fitCameraToPointCloud() {
    // 如果已经有推荐的相机位置，直接使用
    if (defaultCameraPosition.x !== 0 || defaultCameraPosition.y !== 0 || defaultCameraPosition.z !== 50) {
        if (controls && camera) {
            controls.target.set(defaultCameraTarget.x, defaultCameraTarget.y, defaultCameraTarget.z);
            camera.position.set(defaultCameraPosition.x, defaultCameraPosition.y, defaultCameraPosition.z);
            controls.update();
        }
        return;
    }

    // 备用：从点云数据计算边界框
    let points = null;
    if (processedData.originalPointsThreeJS) {
        // 从Three.js格式数据计算
        const positions = processedData.originalPointsThreeJS.positions;
        points = [];
        for (let i = 0; i < positions.length; i += 3) {
            points.push({
                x: positions[i],
                y: positions[i + 1],
                z: positions[i + 2]
            });
        }
    } else if (processedData.originalPoints) {
        points = processedData.originalPoints;
    }

    if (!points || points.length === 0) return;

    const box = new THREE.Box3();

    // 计算点云边界框
    points.forEach(point => {
        box.expandByPoint(new THREE.Vector3(point.x, point.y, point.z));
    });

    const center = box.getCenter(new THREE.Vector3());
    const size = box.getSize(new THREE.Vector3());
    const maxDim = Math.max(size.x, size.y, size.z);

    // 设置相机位置以适应点云
    const distance = maxDim * 2;
    defaultCameraPosition = { x: center.x, y: center.y, z: center.z + distance };
    defaultCameraTarget = { x: center.x, y: center.y, z: center.z };

    // 更新控制器目标
    if (controls) {
        controls.target.set(center.x, center.y, center.z);
        camera.position.set(center.x, center.y, center.z + distance);
        controls.update();
    }
}

// 导出彩色点云数据
async function exportColoredPointCloud() {
    // 检查是否有可导出的数据
    if (!processedData.coloredPoints && !processedData.coloredPointsThreeJS) {
        showError('没有可导出的彩色点云数据，请先完成融合处理');
        return;
    }
    
    if (!processedData.colors && !processedData.coloredPointsThreeJS) {
        showError('没有颜色数据，请先完成融合处理');
        return;
    }

    // 获取用户选择的导出选项
    const includeIntensity = document.getElementById('include-intensity').checked;
    const exportFormat = document.getElementById('export-format').value;
    const filename = document.getElementById('export-filename').value.trim() || 'colored_pointcloud';

    // 验证文件名
    if (!/^[a-zA-Z0-9_\-\u4e00-\u9fa5]+$/.test(filename)) {
        showError('文件名只能包含字母、数字、下划线、连字符和中文字符');
        return;
    }

    try {
        // 准备导出数据
        let exportData;

        if (processedData.coloredPointsThreeJS) {
            // 使用Three.js格式数据（更高效）
            exportData = prepareExportDataFromThreeJS(includeIntensity);
        } else {
            // 使用传统格式数据
            exportData = prepareExportDataFromLegacy(includeIntensity);
        }

        // 首先尝试后端导出，如果失败则使用本地导出
        let backendAvailable = false;
        try {
            // 检查后端是否可用
            const healthResponse = await fetch('http://localhost:5000/api/health', {
                method: 'GET',
                timeout: 2000
            });
            backendAvailable = healthResponse.ok;
        } catch (e) {
            backendAvailable = false;
        }

        if (!backendAvailable) {
            console.log('后端服务不可用，直接使用本地导出');
            exportPointCloudLocal(includeIntensity, exportFormat, filename);
            return;
        }

        const response = await fetch('http://localhost:5000/api/export', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                points: exportData.points,
                colors: exportData.colors,
                include_intensity: includeIntensity,
                format: exportFormat,
                filename: filename
            })
        });

        if (response.ok) {
            const blob = await response.blob();
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `${filename}.${exportFormat}`;
            document.body.appendChild(a);
            a.click();
            // 延迟删除DOM元素以避免错误
            setTimeout(() => {
                if (document.body.contains(a)) {
                    document.body.removeChild(a);
                }
            }, 100);
            window.URL.revokeObjectURL(url);

            console.log(`彩色点云导出成功: ${filename}.${exportFormat}`);

            // 显示成功提示
            showExportSuccess(filename, exportFormat, exportData.points.length, includeIntensity);
        } else {
            const errorData = await response.json();
            throw new Error(errorData.error || '导出失败');
        }
    } catch (error) {
        console.error('后端导出失败，切换到本地导出:', error);
        console.log('使用本地导出功能...');
        // 如果后端不可用，使用前端导出
        exportPointCloudLocal(includeIntensity, exportFormat, filename);
    }
}

// 从Three.js格式数据准备导出数据
function prepareExportDataFromThreeJS(includeIntensity) {
    const positions = processedData.coloredPointsThreeJS.positions;
    const colors = processedData.coloredPointsThreeJS.colors;

    const points = [];
    const exportColors = [];

    for (let i = 0; i < positions.length; i += 3) {
        const point = [positions[i], positions[i + 1], positions[i + 2]];
        points.push(point);

        // 颜色数据（已经是0-1范围）
        const color = [
            Math.round(colors[i] * 255),
            Math.round(colors[i + 1] * 255),
            Math.round(colors[i + 2] * 255)
        ];
        
        // 如果包含intensity，从原始数据中获取真实的intensity值
        if (includeIntensity) {
            const pointIndex = i / 3; // 当前点的索引
            
            // 从fovOriginalPoints获取真实intensity数据（不进行任何计算或替代）
            if (processedData.fovOriginalPoints && 
                processedData.fovOriginalPoints[pointIndex] && 
                processedData.fovOriginalPoints[pointIndex].length >= 4) {
                
                const intensityValue = processedData.fovOriginalPoints[pointIndex][3]; // 直接使用真实值
                color.push(intensityValue);
                
                // 调试信息
                if (pointIndex < 5) {
                    console.log(`Three.js格式intensity调试 (点${pointIndex}):`, {
                        realIntensity: intensityValue,
                        fovOriginalPoint: processedData.fovOriginalPoints[pointIndex],
                        colorLength: color.length
                    });
                }
            } 
            // 备用：从coloredPoints获取intensity
            else if (processedData.coloredPoints && 
                     processedData.coloredPoints[pointIndex]) {
                const intensityValue = processedData.coloredPoints[pointIndex].intensity || 0;
                color.push(intensityValue);
                
                // 调试信息
                if (pointIndex === 0) {
                    console.log(`Three.js格式intensity备用方案:`, {
                        intensityValue,
                        coloredPoint: processedData.coloredPoints[pointIndex],
                        colorLength: color.length
                    });
                }
            } 
            // 最后备用：使用归一化的Z坐标
            else {
                const intensityValue = positions[i + 2];
                color.push(intensityValue);
                
                // 调试信息
                if (pointIndex === 0) {
                    console.log(`Three.js格式intensity最后备用:`, {
                        intensityValue,
                        zCoordinate: positions[i + 2],
                        colorLength: color.length
                    });
                }
            }
        }
        
        exportColors.push(color);
    }

    console.log(`Three.js导出数据准备完成: ${points.length}个点, 包含intensity: ${includeIntensity}`);
    return { points, colors: exportColors };
}

// 从传统格式数据准备导出数据
function prepareExportDataFromLegacy(includeIntensity) {
    const points = processedData.coloredPoints.map(point => {
        return [point.x, point.y, point.z];
    });
    
    const colors = processedData.colors.map((color, index) => {
        const colorData = [color[0], color[1], color[2]];
        // 如果包含intensity，将intensity作为最后一维添加
        if (includeIntensity) {
            // 从原始的fovOriginalPoints中获取真实的intensity数据
            if (processedData.fovOriginalPoints && processedData.fovOriginalPoints[index] && processedData.fovOriginalPoints[index].length >= 4) {
                
                const intensityValue = processedData.fovOriginalPoints[index][3]; // 直接使用真实值
                colorData.push(intensityValue);
                
                // 调试信息
                if (index < 5) {
                    console.log(`Legacy格式intensity调试 (点${index}):`, {
                        realIntensity: intensityValue,
                        fovOriginalPoint: processedData.fovOriginalPoints[index],
                        colorDataLength: colorData.length
                    });
                }
            } else {
                const point = processedData.coloredPoints[index];
                const intensityValue = point.intensity || 0;
                colorData.push(intensityValue);
                
                // 调试信息
                if (index === 0) {
                    console.log(`Legacy格式intensity备用方案:`, {
                        intensityValue,
                        pointIntensity: point.intensity,
                        colorDataLength: colorData.length
                    });
                }
            }
        }
        return colorData;
    });

    return { points, colors };
}

// 本地导出点云数据
function exportPointCloudLocal(includeIntensity = true, format = 'ply', filename = 'colored_pointcloud') {
    console.log(`开始本地导出: ${filename}.${format}, 包含intensity: ${includeIntensity}`);
    
    let exportData;

    if (processedData.coloredPointsThreeJS) {
        exportData = prepareExportDataFromThreeJS(includeIntensity);
        console.log('使用Three.js格式数据导出');
    } else if (processedData.coloredPoints) {
        exportData = prepareExportDataFromLegacy(includeIntensity);
        console.log('使用传统格式数据导出');
    } else {
        showError('没有可导出的点云数据，请先完成融合处理');
        return;
    }

    if (!exportData || !exportData.points || exportData.points.length === 0) {
        showError('导出数据为空，请检查融合处理结果');
        return;
    }

    let content;
    let mimeType = 'text/plain';

    switch (format) {
        case 'ply':
            content = generatePLYContent(exportData.points, exportData.colors, includeIntensity);
            break;
        case 'pcd':
            content = generatePCDContent(exportData.points, exportData.colors, includeIntensity);
            break;
        case 'xyz':
            content = generateXYZContent(exportData.points, exportData.colors, includeIntensity);
            break;
        case 'txt':
            content = generateTXTContent(exportData.points, exportData.colors, includeIntensity);
            break;
        default:
            content = generatePLYContent(exportData.points, exportData.colors, includeIntensity);
            format = 'ply';
    }

    try {
        const blob = new Blob([content], { type: mimeType });
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `${filename}.${format}`;
        a.style.display = 'none';
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        window.URL.revokeObjectURL(url);

        console.log(`点云数据本地导出成功: ${filename}.${format}`);
        console.log(`导出点数: ${exportData.points.length}, 文件大小: ${(content.length / 1024).toFixed(2)} KB`);
        showExportSuccess(filename, format, exportData.points.length, includeIntensity);
    } catch (error) {
        console.error('本地导出失败:', error);
        showError(`导出失败: ${error.message}`);
    }
}

// 生成PLY格式内容
function generatePLYContent(points, colors, includeIntensity) {
    let content = "ply\n";
    content += "format ascii 1.0\n";
    content += `element vertex ${points.length}\n`;
    content += "property float x\n";
    content += "property float y\n";
    content += "property float z\n";
    content += "property uchar red\n";
    content += "property uchar green\n";
    content += "property uchar blue\n";
    
    if (includeIntensity) {
        content += "property float intensity\n";
    }
    
    content += "end_header\n";

    points.forEach((point, index) => {
        const color = colors[index];
        if (includeIntensity && color.length >= 4) {
            // 格式: x y z r g b intensity
            content += `${point[0]} ${point[1]} ${point[2]} ${color[0]} ${color[1]} ${color[2]} ${color[3]}\n`;
        } else {
            // 格式: x y z r g b
            content += `${point[0]} ${point[1]} ${point[2]} ${color[0]} ${color[1]} ${color[2]}\n`;
        }
    });

    return content;
}

// 生成PCD格式内容
function generatePCDContent(points, colors, includeIntensity) {
    const fields = includeIntensity ? "x y z rgb intensity" : "x y z rgb";
    const size = includeIntensity ? "4 4 4 4 4" : "4 4 4 4";
    const type = includeIntensity ? "F F F U F" : "F F F U";
    const count = includeIntensity ? "1 1 1 1 1" : "1 1 1 1";

    let content = "# .PCD v0.7 - Point Cloud Data file format\n";
    content += "VERSION 0.7\n";
    content += `FIELDS ${fields}\n`;
    content += `SIZE ${size}\n`;
    content += `TYPE ${type}\n`;
    content += `COUNT ${count}\n`;
    content += `WIDTH ${points.length}\n`;
    content += "HEIGHT 1\n";
    content += "VIEWPOINT 0 0 0 1 0 0 0\n";
    content += `POINTS ${points.length}\n`;
    content += "DATA ascii\n";

    points.forEach((point, index) => {
        const color = colors[index];
        const rgb = (color[0] << 16) | (color[1] << 8) | color[2];

        if (includeIntensity && color.length >= 4) {
            // 格式: x y z rgb intensity
            content += `${point[0]} ${point[1]} ${point[2]} ${rgb} ${color[3]}\n`;
        } else {
            // 格式: x y z rgb
            content += `${point[0]} ${point[1]} ${point[2]} ${rgb}\n`;
        }
    });

    return content;
}

// 生成XYZ格式内容
function generateXYZContent(points, colors, includeIntensity) {
    let content = "";

    // 调试信息
    console.log(`generateXYZContent调试信息:`, {
        includeIntensity,
        pointsCount: points.length,
        colorsCount: colors.length,
        firstColorSample: colors[0],
        firstColorLength: colors[0] ? colors[0].length : 0,
        前5个colors样本: colors.slice(0, 5)
    });

    points.forEach((point, index) => {
        const color = colors[index];

        if (includeIntensity && color && color.length >= 4) {
            // 格式: x y z r g b intensity
            content += `${point[0]} ${point[1]} ${point[2]} ${color[0]} ${color[1]} ${color[2]} ${color[3]}\n`;
            
            // 调试信息：成功包含intensity
            if (index < 3) {
                console.log(`第${index}个点包含intensity:`, {
                    point,
                    color,
                    intensity: color[3]
                });
            }
        } else {
            // 格式: x y z r g b
            content += `${point[0]} ${point[1]} ${point[2]} ${color[0]} ${color[1]} ${color[2]}\n`;
            
            // 调试信息：为什么没有包含intensity
            if (includeIntensity && index < 3) {
                console.log(`第${index}个点未包含intensity的原因:`, {
                    includeIntensity,
                    colorExists: !!color,
                    colorLength: color ? color.length : 0,
                    colorContent: color
                });
            }
        }
    });

    // 统计有多少点包含了intensity
    let intensityCount = 0;
    points.forEach((point, index) => {
        const color = colors[index];
        if (includeIntensity && color && color.length >= 4) {
            intensityCount++;
        }
    });
    
    console.log(`XYZ导出统计: 总点数=${points.length}, 包含intensity的点数=${intensityCount}`);

    return content;
}

// 生成TXT格式内容
function generateTXTContent(points, colors, includeIntensity) {
    let content = "# Point Cloud Data\n";
    content += `# Format: ${includeIntensity ? 'x y z r g b intensity' : 'x y z r g b'}\n`;
    content += `# Points: ${points.length}\n`;
    content += "#\n";

    return content + generateXYZContent(points, colors, includeIntensity);
}

// 检查后端API连接状态
async function checkBackendConnection() {
    try {
        const response = await fetch('http://localhost:5000/api/health', {
            method: 'GET',
            timeout: 5000
        });

        if (response.ok) {
            const result = await response.json();
            console.log('后端API连接正常:', result.message);
            return true;
        }
    } catch (error) {
        console.warn('后端API连接失败:', error.message);
    }
    return false;
}

// 初始化时检查后端连接
async function initializeBackendConnection() {
    const isConnected = await checkBackendConnection();
    const statusElement = document.getElementById('process-status');

    if (statusElement) {
        if (isConnected) {
            statusElement.textContent = 'API服务已连接';
            statusElement.style.color = '#27ae60';
        } else {
            statusElement.textContent = '离线模式 (API未连接)';
            statusElement.style.color = '#f39c12';
        }
    }
}
